package com.gbas.mus.model;

import com.gbas.mus.model.lances.*;

public class FaseConteo extends Fase {
    public FaseConteo(Ronda ronda) {
        this(ronda, false);
    }

    public FaseConteo(Ronda ronda, boolean byOrdago) {
        super(ronda);

        int equipoGanador = -1;

        if (byOrdago) {
            ronda.juego.finPorOrdago = true;
            // el juego finaliza
            equipoGanador = ronda.juego.vaca.partida.jugarMus.equipoGanador(jugs().jugadorMano, ronda.fases.get(ronda.fases.size() - 1).getClass());
            ronda.juego.finalizaJuego(equipoGanador);

            getJugarMus().accionMesa(Accion.MENSAJE_TEXTO, "Fin de juego por �rdago ganado por " + (equipoGanador + 1));

            //ronda.juego.finalizaJuego(equipoGanador);
        } else {
            getJugarMus().accionMesa(Accion.MENSAJE_TEXTO, "Contando resultados");

            // Sumatorios
            for (Fase f : ronda.fases) {
                if (f instanceof FaseGrandes || f instanceof FaseChicas || f instanceof FasePar || f instanceof FaseJuego) {
                    int valorObtenido = 0;
//                Lance lastLance = f.getLances().get(f.getLances().size() - 1);
                    if (f.getLances().size() > 0 && (f.getLances().get(f.getLances().size() - 1) instanceof LanceVer)) {
                        // Apusta a contabilizar
                        equipoGanador = ronda.juego.vaca.partida.jugarMus.equipoGanador(jugs().jugadorMano, f.getClass());
                        valorObtenido = valorDeEnvites(f);
                        getJugarMus().accionMesa(Accion.MENSAJE_TEXTO, "Apostadas " + valorObtenido + " en " + f.getNombre() + " las gan� " + (1 + equipoGanador));
                    } else if (!hayEnvitesUOrdagos(f)) {
                        // Nadie quiso, se lleva 1 el campeon "en paso" quiza no deba contar 1 en paso par y juego
                        equipoGanador = ronda.juego.vaca.partida.jugarMus.equipoGanador(jugs().jugadorMano, f.getClass());
                        valorObtenido = 1;
                        getJugarMus().accionMesa(Accion.MENSAJE_TEXTO, "Equipo " + (1 + equipoGanador) + " gano 1 en paso en " + f.getNombre());

                    } else {
                        // Hay envites/ordagos cobrados
                        equipoGanador = equipoUltimoEnviteUOrdago(f);
                        getJugarMus().accionMesa(Accion.MENSAJE_TEXTO, "Equipo " + (1 + equipoGanador) + " ya cobr� por " + f.getNombre());

                    }

                    // Ahora en caso de par y juego sumamos los
                    if (f instanceof FasePar) {
                        int valorPar = getValorParEquipo(equipoGanador);
                        valorObtenido += valorPar;
                        getJugarMus().accionMesa(Accion.MENSAJE_TEXTO, "Los pares del equipo " + (1 + equipoGanador) + " suman " + valorPar);

                    }

                    // Si es juego sumamos los puntos del juego
                    if (f instanceof FaseJuego) {
                        int valorPar = 0;
                        if (((FaseJuego) f).alPunto()) {
                            valorPar = 1;
                        } else {
                            valorPar = getValorJuegoEquipo(equipoGanador);
                        }
                        valorObtenido += valorPar;
                        getJugarMus().accionMesa(Accion.MENSAJE_TEXTO, "El juego del equipo " + (1 + equipoGanador) + " suma " + valorPar);
                    }

                    // Sumamos valorObtenido en caso de que valga algo
                    if (ronda.juego.addPuntos(equipoGanador, valorObtenido)) {
                        // Se han salido, el juego finaliza
                        ronda.juego.finalizaJuego(equipoGanador);
                    }
                }
            }
        }

        permiteAccion(jugs().jugadores[0], OP_INPUT.ACEPTA_CONTEO);
        permiteAccion(jugs().jugadores[1], OP_INPUT.ACEPTA_CONTEO, false);
        permiteAccion(jugs().jugadores[2], OP_INPUT.ACEPTA_CONTEO, false);
        permiteAccion(jugs().jugadores[3], OP_INPUT.ACEPTA_CONTEO, false);
    }

    private int getValorJuegoEquipo(int equipoGanador) {
        int valroJuego = 0;
        for (JugadorMus jmus : jugs().jugadores) {
            if (jmus.equipo == equipoGanador) {
                if (cuentaPuntos(jmus.getNaipes()) == 31) {
                    valroJuego += 3;
                } else if (cuentaPuntos(jmus.getNaipes()) > 31) {
                    valroJuego += 2;
                }
            }
        }
        return valroJuego;
    }

    private int getValorParEquipo(int equipoGanador) {
        int valorPar = 0;
        for (JugadorMus jmus : jugs().jugadores) {
            if (jmus.equipo == equipoGanador) {
                valorPar += getValorPares(jmus.getNaipes());
            }
        }
        return valorPar;
    }

    public boolean lanceValido(Lance lance) {
        return lance instanceof LanceAceptoConteo;
    }

    public void doLance(Lance lance) {
        if (lances.size() == 4) {
            ronda.finalizaRonda();
            if (ronda.juego.stado == 0) {
                ronda.juego.nuevaRonda();
            } else {
                ronda.juego.vaca.juegoFinalizado();
            }
        }
    }

    public String getNombre() {
        return "Conteo";
    }

    public int valorDeEnvites(Fase f) {
        int valor = 0;
        for (Lance l : f.getLances()) {
            if (l instanceof LanceEnvido) {
                valor += ((LanceEnvido) l).getCantidad();
            }
        }
        return valor;
    }

    private boolean hayEnvitesUOrdagos(Fase f) {
        for (Lance l : f.getLances()) {
            if (l instanceof LanceEnvido || l instanceof LanceOrdago) {
                return true;
            }
        }
        return false;
    }

    private int equipoUltimoEnviteUOrdago(Fase f) {
        int lastEquipo = -1;
        for (Lance l : f.getLances()) {
            if (l instanceof LanceEnvido || l instanceof LanceOrdago) {
                lastEquipo = l.getJugador().equipo;
            }
        }
        return lastEquipo;
    }

}
